


function deepClone(origin) {
  if (typeof origin !== 'object' || !origin) {
    return origin
  }
  const target = new origin.constrcutor();
  for (let k in origin) {
    if (origin.hasOweProperty(k)) {
      target[k] = deepClone(origin[k])
    }
  }
  return target
}

function deepClone2(origin, target) {

  let item = null;
  for (let k in origin) {
    item = origin[k];
    if (item instanceof Array) {
      target[k] = [];
      deepClone(item, target[k])
    } else if (item instanceof Object) {
      target[k] = {};
      deepClone(item, target[k])
    } else {
      target[k] = item
    }
  }
  return target
}



Array.prototype.myForEach = function (cb) {
  const arr = this;
  const len = this.length;
  const arg1 = arguments[1] || window;
  for (let i = 0; i < len; i++) {
    cb.apply(arg1, [arr[i], i, arr])
  }
}





Array.prototype.myMap = function (cb) {
  const arr = this;
  const len = this.length;
  const arg1 = arguments[1] || window;
  let item, newArr = [];
  for (let i = 0; i < len; i++) {
    cb.apply(arg1, [arr[i], i, arr]) ? saveItem(i) : ''
  }
  function saveItem(i) {
    item = deepClone(arr[i]);
    newArr.push(item);
  }
  return newArr;
}



Array.prototype.mySome = function (cb) {
  const arr = this;
  const len = this.length;
  const arg1 = arguments[1] || window;
  let res = false;
  for (let i = 0; i < len; i++) {
    if (cb.apply(arg1, [arr[i], i, arr])) {
      res = true;
      break;
    }
  }
  return res
}




Array.prototype.myFilter = function (cb) {
  const arr = this;
  const len = this.length;
  const arg1 = arguments[1] || window;
  let item = null, newArr = [];
  for (let i = 0; i < len; i++) {
    cb.apply(arg1, [item, i, arr]) ? saveItem(i) : ''
  }
  function saveItem(i) {
    item = deepClone(arr[i]);
    newArr.push(item)
  }
  return newArr
}
Array.prototype.myReduce = function (cb, initial) {
  const arr = this;
  const len = this.length;
  const args = arguments[1] || window;
  let item = null
  for (let i = 0; i < len; i++) {
    item = deepClone(arr[i])
    initial = cb.apply(args, [initial, item, i, arr])
  }
  return initial
}